package com.woniu.websocket;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 专用于发送医护通知的 WebSocket 端点。
 * 它不修改现有的 WebSocketConfig。
 */
@ServerEndpoint("/ws/notify/{staffId}") // <-- 关键：前端将通过此 URL 连接
@Component
public class NotificationServerEndpoint {

    /**
     * 静态 Map，用于存储 staffId -> Session 的映射。
     * 必须是 static 才能被 Service 层调用。
     */
    private static final Map<Integer, Session> sessionMap = new ConcurrentHashMap<>();
    private static final ObjectMapper objectMapper = new ObjectMapper();

    /**
     * 当一个新连接打开时调用
     * @param session WebSocket 会话
     * @param staffId 从 URL 路径中提取的用户ID
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("staffId") Integer staffId) {
        if (staffId == null || staffId == 0) {
            System.err.println("WebSocket OnOpen: staffId 不能为空，连接关闭。");
            closeSession(session);
            return;
        }

        // 存储 session
        sessionMap.put(staffId, session);
        System.out.println("WebSocket 通知服务：医生 " + staffId + " 已连接。");
    }

    /**
     * 当连接关闭时调用
     */
    @OnClose
    public void onClose(Session session, @PathParam("staffId") Integer staffId) {
        if (staffId != null) {
            sessionMap.remove(staffId);
            System.out.println("WebSocket 通知服务：医生 " + staffId + " 已断开。");
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        System.err.println("WebSocket 发生错误: " + error.getMessage());
        // (您可以在这里添加 onClose 的逻辑，以确保 Map 被清理)
    }

    /**
     * (可选) 接收客户端心跳
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        // 例如，如果前端发送 "PING"，我们回复 "PONG" 来保持连接
        if ("PING".equals(message)) {
            try {
                session.getBasicRemote().sendText("PONG");
            } catch (IOException e) {
                // ...
            }
        }
    }

    /**
     *  核心静态方法：从 Service (非 WebSocket 环境) 调用此方法
     * @param staffId 目标医生/员工的ID
     * @param messagePayload 包含消息内容的对象
     */
    public static void sendToUser(Integer staffId, Map<String, String> messagePayload) {
        Session session = sessionMap.get(staffId);

        if (session != null && session.isOpen()) {
            try {
                String message = objectMapper.writeValueAsString(messagePayload);
                session.getBasicRemote().sendText(message);
                System.out.println("WebSocket 成功发送消息给 " + staffId);
            } catch (IOException e) {
                System.err.println("WebSocket 发送消息失败: " + e.getMessage());
            }
        } else {
            System.out.println("WebSocket 发送失败: 用户 " + staffId + " 不在线。");
        }
    }

    // 辅助方法：关闭会话
    private void closeSession(Session session) {
        try {
            session.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}